package com.bardsoftware.foronuvolo.server;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;

import com.bardsoftware.foronuvolo.data.CollectionsUtil;
import com.bardsoftware.foronuvolo.data.Discussion;
import com.bardsoftware.foronuvolo.data.DiscussionChunk;
import com.bardsoftware.foronuvolo.data.DiscussionsViewItem;
import com.bardsoftware.foronuvolo.data.FeedItem;
import com.bardsoftware.foronuvolo.data.Message;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.repackaged.com.google.common.base.Pair;
import com.google.appengine.repackaged.com.google.common.collect.ImmutableList;
import com.google.appengine.repackaged.com.google.common.collect.Lists;

public class DiscussionsViewPage implements Serializable {
    private static final Cache ourCache;
    private static final MessageCache<Key,Pair<String,Boolean>> ourMessageTextCache;
    private static final MessageCache<String, DiscussionsViewPage> ourDiscussionViewItemCache;
    private static final WikiMessageFormatter myFormatter = new WikiMessageFormatter(WikiMessageFormatter.LONG_TEXT_THRESHOLD);

    private List<DiscussionsViewItem> myItems;
    private String myNextPageID;
    private String myPrevPageID;

    static {
        Cache cache;
        try {
            cache = CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());
        }
        catch (CacheException e) {
            cache = null;
        }
        ourCache = cache;
        ourMessageTextCache = new MessageCache<Key, Pair<String,Boolean>>(ourCache, "t");
        ourDiscussionViewItemCache = new MessageCache<String, DiscussionsViewPage>(ourCache, "dvi");
        ourDiscussionViewItemCache.setVersioned(true);
        MessageCache.addDiscussionCache(ourDiscussionViewItemCache);
    }

    public static void resetDiscussionViewPageCache() {
        MessageCache.onDiscussionSetChange();
    }


    public DiscussionsViewPage() {
        myItems = ImmutableList.of();
        myNextPageID = "";
        myPrevPageID = "";
    }

    public DiscussionsViewPage(DiscussionChunk chunk) {
        myItems = createForumViewItems(chunk);
        myNextPageID = chunk.getNextChunkID();
        myPrevPageID = chunk.getPrevChunkID();
    }

    String getNextPageID() {
        return myNextPageID;
    }

    String getPrevPageID() {
        return myPrevPageID;
    }

    List<DiscussionsViewItem> getItems() {
        return myItems;
    }

    static DiscussionsViewPage getPage(DiscussionChunk chunk) {
        String chunkID = chunk.getID();
        DiscussionsViewPage result = ourDiscussionViewItemCache.get(chunkID);
        if (result != null) {
            return result;
        }
        result = new DiscussionsViewPage(chunk);
        ourDiscussionViewItemCache.put(chunkID, result);
        return result;
    }

    private static List<DiscussionsViewItem> createForumViewItems(DiscussionChunk page) {
        List<DiscussionsViewItem> result = Lists.newArrayListWithCapacity(page.getDiscussions().size());
        for (Discussion d: page.getDiscussions()) {
            result.add(new DiscussionsViewItem(d, ourMessageTextCache, myFormatter));
        }
        return result;
    }

    Date addUpdatedMessagesSince(List<FeedItem> items, Discussion d, Date startDate) {
        Date lastUpdate = null;
        Collection<Message> replies = d.getSortedMessages();
        for (Message m: replies) {
            if (m.getCreation().after(startDate)) {
                items.add(new FeedItem(d, m, ourCache, myFormatter));
                if (lastUpdate == null) {
                    lastUpdate = m.getCreation();
                }
            } else {
                break;
            }
        }
        if (lastUpdate == null) {
            lastUpdate = CollectionsUtil.first(replies).getCreation();
        }
        return lastUpdate;
    }
}
